
#include <stdlib.h>
#include <iostream>
#include <string>
#include <vector>
#include "calculsoustableau.h"

void calcule::calculSousTableau (vector<int> *cgh,int *g,int *h,struct result *resultatfinal){
//declaration des variables
    std::cout<<"declaration variable de la fonction calcul sous tableau"<<endl;
    struct result resultat;
    vector<int> ssum((*cgh).size());
    vector<int> pmax((*cgh).size());
    vector<int> psum((*cgh).size());
    vector<int> smax((*cgh).size());
    vector<int> m((*cgh).size());
    int mmax;
    int y0;
    int y1;
//creation objet
    calcule1 calc1;
    calcule2 calc2;
    calculefinal calcf;
//declaration des pointeurs
    vector<int> *pssum;
    vector<int> *ppmax;
    vector<int> *ppsum;
    vector<int> *psmax;
    vector<int> *pm;
    int *y0_p;
    int *y1_p;
//affectation des pointeurs
    pssum=&ssum;
    ppsum=&psum;
    ppmax=&pmax;
    psmax=&smax;
    pm=&m;
    y0_p=&y0;
    y1_p=&y1;
//créer un thread pour le calcul de psum smax
    std::cout<<"calcul psum"<<endl;
    calc2.calc_psum(cgh,ppsum);
    std::cout<<"calcul smax)"<<endl;
    calc2.calc_smax(ppsum,psmax);
//créer un tr=hread pour le calcul de ssum pmax
    std::cout<<"calcul ssum"<<endl;
    calc1.calc_ssum(cgh,pssum);
    std::cout<<"calcul pmax"<<endl;
    calc1.calc_pmax(pssum,ppmax);
//attendre la fin calcul psum,ssum,pmax et smax
    std::cout<<"calcul M"<<endl;
    mmax=calcf.calculM(y0_p,y1_p,cgh,pssum,ppsum,ppmax,psmax,pm);
    std::cout<<"Mise en forme du resultat"<<endl;
    //mise en forme du resultat
    resultat.y0=y0;
    resultat.y1=y1;
    resultat.m=mmax;
    resultat.x0=*g;
    resultat.x1=*h;
//envoi du resultat si resultat plus grand que celui deja presant
    if((*resultatfinal).m<resultat.m){
        *resultatfinal=resultat;

    }
    std::cout<<"resultat x0 = "<<resultat.x0<<" x1 = "<<resultat.x1<<" y0 = "<<resultat.y0<<" y1 = "<<resultat.y1<<" M = "<<resultat.m<<endl;
    std::cout<<"fin sstableau"<<endl;
}


//calcul ssum la somme des suffixes du tableau cgh
void calcule1::calc_ssum(vector<int> *cgh,vector<int> *pssum){
    (*pssum)[0]=(*cgh)[0];
    std::cout<<"ssum(0) = "<<((*pssum)[0])<<endl;
    for (int i=1;i<=(*cgh).size()-1;i++){
        (*pssum)[i]=(*cgh)[i]+(*pssum)[i-1];
        std::cout<<"ssum("<<i<<") = "<<((*pssum)[i])<<endl;
        }
}
//calcul pmax inscrit la valeur la plus forte rencontré dans un case en lisant ssum de la droite vers la gauche
void calcule1::calc_pmax(vector<int> *ssum,vector<int> *pmax){
    int pmmax = (*ssum)[(*ssum).size()-1];
    //std::cout<<"pmmax = "<<pmmax<<endl;
    for(int i=(*ssum).size()-1;i>=0;i--){
        //std::cout<<"ssum("<<i<<") = "<<ssum[i]<<endl;
        if((*ssum)[i]>pmmax){
            pmmax=(*ssum)[i];
            //std::cout<<"pmmax = "<<pmmax<<endl;
        }
        (*pmax)[i]=pmmax;
        std::cout<<"pmax("<<i<<") = "<<(*pmax)[i]<<endl;
    }
}

//calcul psum calcule la somme des prefixes
void calcule2::calc_psum(vector<int> *cgh,vector<int> *psum){
    (*psum)[(*cgh).size()-1]=(*cgh)[(*cgh).size()-1];
    std::cout<<" psum(3) = "<<(*psum)[(*cgh).size()-1]<<endl;
    for(int i=(*cgh).size()-2;i>=0;i--){
        //std::cout<<"i= "<<i<<endl;
        (*psum)[i]=(*cgh)[i]+(*psum)[i+1];
        std::cout<<" psum("<<i<<") = "<<(*psum)[i]<<endl;
    }
}

//calcul smax inscrit la valeur la plus forte rencontré dans un case en lisant psum de la gauche vers la droite
void calcule2::calc_smax(vector<int> *psum,vector<int> *smax){
    int smmax=(*psum)[0];
    //std::cout<<" smmax = "<<smmax<<endl;
    for(int i=0;i<=(*psum).size()-1;i++){
        //std::cout<<" psum("<<i<<") = "<<psum[i]<<endl;
        if((*psum)[i]>smmax){
            smmax=(*psum)[i];
            //std::cout<<" smmax = "<<smmax<<endl;
        }
        (*smax)[i]=smmax;
        std::cout<<" smax("<<i<<") = "<<(*smax)[i]<<endl;
    }

}

//calcul m valeur max du sous tableau optimal de la ligne et sa position dans le tableau cgh
int calculefinal::calculM(int *y0,int *y1,vector<int> *cgh,vector<int> *ssum,vector<int> *psum,vector<int> *pmax,vector<int> *smax,vector<int> *m){
    std::cout<<"debut M"<<endl;
    int mmax;
//calcul du tableau de m
    std::cout<<"calcul du tableau de m"<<endl;
    for(int i=0;i<=(*cgh).size()-1;i++){
        (*m)[i]=(*pmax)[i]+(*smax)[i]-(*psum)[i]-(*ssum)[i]+(*cgh)[i];
        std::cout<<" m("<<i<<") = "<<(*m)[i]<<endl;
    }
//recherche de la valeur de m la plus grande
    std::cout<<"recherche de la valeur de m la plus grande"<<endl;
    mmax=(*m)[1];
    for(int i=1;i<=(*cgh).size()-1;i++){
        if((*m)[i]>mmax){
            mmax=(*m)[i];
        }
    }
//recherche fin de la suite de valeur mmax
    std::cout<<"recherche fin de la suite de valeur mmax"<<endl;
    *y1=(*cgh).size()-1;
    for(int i=1;i<=(*cgh).size()-1;i++){
        if((*m)[i-1]>(*m)[i] && (*m)[i-1]==mmax){
            *y1=i-1;
        }
    }
//recherche du debut de la suite de valeur mmax
    std::cout<<"recherche du debut de la suite de valeur mmax"<<endl;
    *y0=0;
    for(int i=(*cgh).size()-1;i>=1;i--){
        std::cout<<"i = "<<i<<endl;
        if((*m)[i-1]<(*m)[i] && (*m)[i]==mmax){
            *y0=i;
        }
    }
    return mmax;
    }

